﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Threading;
using Avivo.Tools.Sprite;
using Microsoft.Expression.Framework;

namespace Sprite.Blend.AddIn
{
	public class SpriteContractService : IContractService, INotifyPropertyChanged
	{
		#region Constructors
		public SpriteContractService()
		{
		}

		public SpriteContractService(IApplicationService appService)
		{
			RegisterApplicationService(appService);
		}
		#endregion

		#region Public properties
		private IApplicationService appService;
		public IApplicationService AppService
		{
			get
			{
				return this.appService;
			}
		}
		#endregion

		#region Public methods
		public void RegisterApplicationService(IApplicationService appService)
		{
			this.appService = appService;
			InitializeAddin();
		}
		#endregion

		#region Protected methods
		protected void InitializeAddin()
		{
			if (appService == null)
			{
				ReportError(new Exception("appService is null, plugin cannot be loaded!"));
			}
			else
			{
				//TODO: Find a better trigger instead of timer
				DispatcherTimer timer = new DispatcherTimer();
				timer.Interval = TimeSpan.FromSeconds(1);
				timer.Tick += (sender, e) =>
				{
					try
					{
						LoadDocumentElement();
					}
					catch
					{
					}
				};
				timer.Start();
			}
		}

		protected void LoadDocumentElement()
		{
			if (this.DocumentPath != appService.DocumentService.ActiveDocument.DocumentReference.Path)
			{
				this.DocumentPath = appService.DocumentService.ActiveDocument.DocumentReference.Path;
				OnDocumentChanged();
			}
		}

		protected void ReportError(Exception error)
		{
			if (appService != null && error != null)
			{
				//Display message in application's logging window
				appService.MessageLoggingService.WriteLine(error.Message);
			}
		}
		#endregion

		#region IContractService Members
		public string DocumentPath
		{
			get
			{
				return this.documentPath;
			}
			set
			{
				if (this.documentPath != value)
				{
					this.documentPath = value;
					OnPropertyChanged("DocumentPath");
				}
			}
		}
		private string documentPath;

		public FrameworkElement DocumentContent
		{
			get
			{
				return this.documentContent;
			}
			set
			{
				if (this.documentContent != value)
				{
					this.documentContent = value;
					OnPropertyChanged("DocumentContent");
				}
			}
		}
		private FrameworkElement documentContent;

		public void WriteLine(string message)
		{
			if (this.appService != null)
			{
				this.appService.MessageLoggingService.WriteLine(message);
			}
		}

		public event EventHandler DocumentChanged;
		protected virtual void OnDocumentChanged()
		{
			if (DocumentChanged != null)
			{
				DocumentChanged(this, new EventArgs());
			}
		}
		#endregion

		#region INotifyPropertyChanged Members
		public event PropertyChangedEventHandler PropertyChanged;
		protected virtual void OnPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}
		#endregion
	}
}
